package com.smt.ejb3.tutoria.service.impl;

import java.util.List;
import java.util.Set;

import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import com.smt.ejb3.tutoria.entitybean.jointable.Buyer;
import com.smt.ejb3.tutoria.entitybean.jointable.User;
import com.smt.ejb3.tutoria.entitybean.many2many.Role;
import com.smt.ejb3.tutoria.entitybean.many2many.Staff;
import com.smt.ejb3.tutoria.entitybean.many2one.Company;
import com.smt.ejb3.tutoria.entitybean.many2one.Employee;
import com.smt.ejb3.tutoria.entitybean.many2one.bidirection.Company2;
import com.smt.ejb3.tutoria.entitybean.one2one.fk.Customer1;
import com.smt.ejb3.tutoria.entitybean.one2one.fk.CustomerNo1;
import com.smt.ejb3.tutoria.entitybean.one2one.pk.Customer;
import com.smt.ejb3.tutoria.entitybean.one2one.pk.CustomerNo;
import com.smt.ejb3.tutoria.entitybean.singletable.Animal;
import com.smt.ejb3.tutoria.entitybean.tableperclass.Meat;
import com.smt.ejb3.tutoria.service.MappingService;

@Stateless
@Remote(MappingService.class)
public class MappingServiceImpl implements MappingService {

	@PersistenceContext(unitName = "ejb3db")
	private EntityManager em;

	@Override
	public Employee saveEmployee(Employee emp){
		Company company = emp.getCompany();
		Query query = em.createQuery("select c from Company c where c.name = :name").setParameter("name", company.getName());
		@SuppressWarnings("unchecked")
		List<Company> result = query.getResultList();
		if(result.size() == 0){
			em.persist(company);
		}
		try {
			em.persist(emp);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return emp;
	}

	@Override
	public void testSave() {
		Company company = new Company();
		company.setName("IBM");

		Employee emp = new Employee();
		emp.setName("Old Sun");
		emp.setCompany(company);

		Employee emp2 = new Employee();
		emp2.setName("Old Change");
		emp2.setCompany(company);

		em.persist(emp);
		em.persist(emp2);

	}

	@Override
	public Company2 saveCompany2(Company2 com) {
		try {
			em.persist(com);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return com;
	}

	@Override
	public Company2 findCompany2(int id) {
		return em.find(Company2.class, id);
	}

	@Override
	public Customer saveCustomer(Customer cus) {
		try {
			em.persist(cus);
			CustomerNo cno = cus.getCustNo();
			cno.setId(cus.getId());
			em.persist(cno);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return cus;
	}

	@Override
	public Customer findCustomer(int id) {
		return em.find(Customer.class, id);
	}

	@Override
	public CustomerNo findCustomerNo(int id) {
		return em.find(CustomerNo.class, id);
	}

	@Override
	public Customer1 saveCustomer1(Customer1 cus) {
		try {
			em.persist(cus);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return cus;
	}

	@Override
	public Customer1 findCustomer1(int id) {
		return em.find(Customer1.class, id);
	}

	@Override
	public CustomerNo1 findCustomerNo1(int id) {
		return em.find(CustomerNo1.class, id);
	}

	@Override
	public Role saveRole(Role role) {
		Set<Staff> staffs = role.getStaffs();
		for(Staff staff: staffs){
			Staff dbStaff = findStaff(staff.getName());
			if(dbStaff != null){
				staff.setId(dbStaff.getId());
			}else{
				staff.setId(saveStaff(staff).getId());
			}
		}
		try {
			em.persist(role);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return role;
	}

	@Override
	public Staff findStaff(String name) {
		Query query = em.createQuery("select s from Staff s where s.name = :name")
			.setParameter("name", name);
		Query query2 = em.createQuery("select s from Staff s where s.name = ?")
			.setParameter("1", name); //Hibernate starts from 0
		@SuppressWarnings("unchecked")
		List<Staff> result = query.getResultList();
		if(result.size() == 1){
			return result.get(0);
		}else if(result.size() == 0){
			return null;
		}else{
			System.out.println("Cannot reach here");
			return null;
		}
		
	}

	@Override
	public Staff saveStaff(Staff staff) {
		try {
			em.persist(staff);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return staff;
	}

	@Override
	public Role findRole(int id) {
		return em.find(Role.class, id);
	}

	@Override
	public Animal saveAnimal(Animal animal) {
		try {
			em.persist(animal);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return animal;
	}

	@Override
	public User saveUser(User user) {
		try {
			em.persist(user);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return user;
	}

	@Override
	public Buyer findBuyer(int id) {
		return em.find(Buyer.class, id);
	}

	@Override
	public Meat saveMeat(Meat meat) {
		try {
			em.persist(meat);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return meat;
	}

	@Override
	public User findUser(int id) {
		return em.find(User.class, id);
	}

	@Override
	public Meat findMeat(int id) {
		return em.find(Meat.class, id);
	}

}
